package com.fight.strive.sys.modules.rbac.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fight.strive.sys.modules.common.PageR;
import com.fight.strive.sys.modules.exception.StriveException;
import com.fight.strive.sys.modules.mybatis.MyBatisPlusUtils;
import com.fight.strive.sys.modules.rbac.dao.RbacRoleMapper;
import com.fight.strive.sys.modules.rbac.entity.RbacRoleEntity;
import com.fight.strive.sys.modules.rbac.service.RbacDepartmentRoleService;
import com.fight.strive.sys.modules.rbac.service.RbacRoleService;
import com.fight.strive.sys.modules.rbac.service.RbacUserRoleService;
import com.fight.strive.sys.utils.CollectionUtils;
import com.fight.strive.sys.utils.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RbacRoleServiceImpl
        extends ServiceImpl<RbacRoleMapper, RbacRoleEntity>
        implements RbacRoleService {

    @Resource
    private RbacUserRoleService rbacUserRoleService;

    @Resource
    private RbacDepartmentRoleService rbacDepartmentRoleService;

    @Override
    public void saveRole(RbacRoleEntity entity) {
        try {
            this.saveOrUpdate(entity);
        } catch (DuplicateKeyException e) {
            throw new StriveException("角色代码已存在");
        }
    }

    @Override
    public IPage<RbacRoleEntity> listByPage(PageR<RbacRoleEntity> page) {
        QueryWrapper<RbacRoleEntity> queryWrapper = new QueryWrapper<>();
        MyBatisPlusUtils.buildRuleQuery(queryWrapper, page);
        if (ObjectUtils.notNull(page.getCondValue("userId"))) {
            // 人员角色查询
            queryWrapper.exists("select id from t_sys_rbac_user_role " +
                            "where role_id = t_sys_rbac_role.id and user_id = '{0}'",
                    page.getCondValue("userId"));
        }
        if (ObjectUtils.notNull(page.getCondValue("departmentId"))) {
            // 部门角色查询
            queryWrapper.exists("select id from t_sys_rbac_department_role " +
                            "where role_id = t_sys_rbac_role.id and department_id = '{0}'",
                    page.getCondValue("departmentId"));
        }
        queryWrapper.orderByAsc("seq");
        return this.page(page, queryWrapper);
    }

    @Override
    public List<RbacRoleEntity> listByUserId(Long userId) {
        QueryWrapper<RbacRoleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.exists("select id from t_sys_rbac_user_role " +
                "where role_id = t_sys_rbac_role.id and user_id = '{0}'", userId);
        queryWrapper.orderByAsc("seq");
        return this.list(queryWrapper);
    }

    @Override
    public Map<String, Boolean> getRoleByUserId(Long userId) {
        List<RbacRoleEntity> roles = this.listByUserId(userId);
        if (CollectionUtils.isNotEmpty(roles)) {
            Map<String, Boolean> roleCodeMap = roles.stream()
                    .collect(Collectors.toMap(RbacRoleEntity::getCode, (item) -> true));
        }
        return Collections.emptyMap();
    }

    @Override
    public List<RbacRoleEntity> listByDepartmentId(Long departmentId) {
        QueryWrapper<RbacRoleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.exists("select id from t_sys_rbac_department_role " +
                "where role_id = t_sys_rbac_role.id and department_id = '{0}'", departmentId);
        queryWrapper.orderByAsc("seq");
        return this.list(queryWrapper);
    }

    @Override
    public Map<String, Boolean> getRoleByDepartmentId(Long departmentId) {
        List<RbacRoleEntity> roles = this.listByDepartmentId(departmentId);
        if (CollectionUtils.isNotEmpty(roles)) {
            Map<String, Boolean> roleCodeMap = roles.stream()
                    .collect(Collectors.toMap(RbacRoleEntity::getCode, (item) -> true));
        }
        return Collections.emptyMap();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeRole(RbacRoleEntity entity) {
        // 根据角色ID删除部门角色关联信息
        rbacDepartmentRoleService.removeByRoleId(entity.getId());
        // 根据角色ID删除用户角色关联信息
        rbacUserRoleService.removeByRoleId(entity.getId());
        this.removeById(entity);
    }
}
